package com.hezhiqin.config;

import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEvent;

/**
 * @description:
 * @author: hezhiqin
 * @time: 2020/7/14 15:43
 */
public class DynamicMqttClient extends ApplicationEvent {


    private String username;


    private String password;


    private String hostUrl;


    private String clientId;


    private String defaultTopic;


    private int completionTimeout;   //连接超时


    private volatile MqttClient mqttClient;
    private MqttConnectOptions options;

    public MqttClient getMqttClient() {
        return mqttClient;
    }

    public void setMqttClient(MqttClient mqttClient) {
        mqttClient = mqttClient;
    }

    public MqttConnectOptions getOptions() {
        return options;
    }

    public static void setOptions(MqttConnectOptions options) {
        options = options;
    }

    public DynamicMqttClient(String username, String password, String hostUrl, String clientId, String defaultTopic, int completionTimeout) {
        super(clientId);
        this.username = username;
        this.password = password;
        this.hostUrl = hostUrl;
        this.clientId = clientId;
        this.defaultTopic = defaultTopic;
        this.completionTimeout = completionTimeout;
    }


    public void connection() {
        try {
            // host为主机名，clientid即连接MQTT的客户端ID，一般以客户端唯一标识符表示，
            // MemoryPersistence设置clientid的保存形式，默认为以内存保存

            mqttClient = new MqttClient(hostUrl, clientId, new MemoryPersistence());
            // 配置参数信息
            options = new MqttConnectOptions();
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，
            // 这里设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);
            // 设置用户名
            options.setUserName(username);
            // 设置密码
            options.setPassword(password.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(completionTimeout);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
            // 连接
            mqttClient.connect(options);
            // 订阅
            mqttClient.subscribe(defaultTopic);
            // 设置回调
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {
                    System.out.println("已关闭连接" + mqttClient.getClientId());
                }

                @Override
                public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
                    System.out.println("currentThread:" + Thread.currentThread().getName() + "Topic: " + s + " Message: " + mqttMessage.toString());
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {

                    System.out.println("keyi l " + iMqttDeliveryToken.getActionCallback());
                }
            });
        } catch (Exception e) {
            try {
                mqttClient.unsubscribe(defaultTopic);
                mqttClient.close();

            } catch (MqttException mqttException) {
                mqttException.printStackTrace();
            }
            e.printStackTrace();
        }
    }

    public void reconnection(MqttClient mqttClient, String username, String password, String hostUrl, String clientId, String defaultTopic, int completionTimeout) {
        try {

            // 配置参数信息
            options = new MqttConnectOptions();
            // 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，
            // 这里设置为true表示每次连接到服务器都以新的身份连接
            options.setCleanSession(true);
            // 设置用户名
            options.setUserName(username);
            // 设置密码
            options.setPassword(password.toCharArray());
            // 设置超时时间 单位为秒
            options.setConnectionTimeout(10);
            // 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
            options.setKeepAliveInterval(20);
            // 连接
            mqttClient.connect(options);
            // 订阅
            mqttClient.subscribe(defaultTopic);

            mqttClient.reconnect();
            // 设置回调
            mqttClient.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable throwable) {
                    System.out.println("connectionLost");
                }

                @Override
                public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
                    System.out.println("currentThread:" + Thread.currentThread().getName() + "Topic: " + s + " Message: " + mqttMessage.toString());
                }

                @Override
                public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                    iMqttDeliveryToken.getActionCallback();
                }
            });
        } catch (Exception e) {
            try {
                mqttClient.unsubscribe(defaultTopic);
                mqttClient.close();

            } catch (MqttException mqttException) {
                mqttException.printStackTrace();
            }
            e.printStackTrace();
        }
    }





}
